﻿using Authority.Model;
using Common.Library;
using Microsoft.AspNetCore.Mvc.Filters;
using Network.Library;
using Redis.Library;
using System;
using System.Collections.Generic;
using Tool.Model;

namespace Web.Manage.App_Start
{
    /// 用户授权特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class UserAuthorizationAttribute : ActionFilterAttribute
    {
        //操作类型  1登录 2页面 3功能
        private FunctionValidateType functionType = FunctionValidateType.VerifyLoggedIn;
        //是否需要验证
        private bool isValidate = false;
        //按钮授权码
        private ButtonAuthorizationCode buttonAuthorizationCode;

        /// <summary>
        /// 验证用户信息
        /// </summary>
        /// <param name="isOrgUser">是否验证</param>
        /// <param name="functionType">操作类型  1登录 2页面 3功能</param>
        public UserAuthorizationAttribute(bool isValidate, FunctionValidateType functionType)
        {
            this.functionType = functionType;
            this.isValidate = isValidate;
        }

        /// <summary>
        /// 验证用户信息
        /// </summary>
        /// <param name="isOrgUser">是否验证</param>
        /// <param name="functionType">操作类型  1登录 2页面 3功能</param>
        /// <param name="buttonAuthorizationCode">按钮授权码</param>
        public UserAuthorizationAttribute(bool isValidate, FunctionValidateType functionType, ButtonAuthorizationCode authorizationCode)
        {
            this.functionType = functionType;
            this.isValidate = isValidate;
            this.buttonAuthorizationCode = authorizationCode;
        }


        /// <summary>
        ///  验证用户信息
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            #region 权限验证

            if (isValidate)
            {
                var userInfo = UserSession.GetLoginUser<SysUserInfo>();
                switch (this.functionType)
                { 
                    //验证登陆
                    case FunctionValidateType.VerifyLoggedIn:
                        if (userInfo == null || string.IsNullOrEmpty(userInfo.Code))
                        {
                            ActionException(filterContext, "无用户信息，请重新登录！");
                        }
                        break;
                    //验证界面
                    case FunctionValidateType.VerifyView:
                        if (userInfo == null || string.IsNullOrEmpty(userInfo.Code))
                        {
                            ActionException(filterContext, "无用户信息，请重新登录！");
                        }
                        else
                        {
                            string pathUrl = filterContext.HttpContext.Request.Path;
                            //可操作菜单
                            var sysMenuList = RedisClient.GetRedisDb(ConstRedisKey.RedisDbWeb)
                                .HashGet<List<SysMenuEntity>>(ConstRedisKey.RedisMenusCode, userInfo.LoginName);
                            //获取当前菜单
                            var menuInfo = sysMenuList.Find(p => p.sUrl == pathUrl);
                            if (menuInfo == null)
                            {
                                ActionException(filterContext, "无操作该菜单的权限！");
                            }
                        }
                        break;
                    //验证方法
                    case FunctionValidateType.VerifyAction:
                        if (userInfo == null || string.IsNullOrEmpty(userInfo.Code))
                        {
                            ActionException(filterContext, "无用户信息，请重新登录！");
                        }
                        else
                        {
                            string pathUrl = filterContext.HttpContext.Request.Path.ToString();
                            var pathUrls = pathUrl.Split('/');
                            pathUrl=pathUrl.Replace(pathUrls[pathUrls.Length-1], "Index");

                            //可操作按钮
                            var info = RedisClient.GetRedisDb(ConstRedisKey.RedisDbWeb)
                                .HashGet<List<SysUserRoleButtonsInfo>>(ConstRedisKey.RedisButtonsCode, userInfo.LoginName);

                            //可操作菜单
                            var sysMenuList = RedisClient.GetRedisDb(ConstRedisKey.RedisDbWeb)
                                .HashGet<List<SysMenuEntity>>(ConstRedisKey.RedisMenusCode, userInfo.LoginName);

                            //获取当前菜单编码
                            var gMenuCode = sysMenuList.Find(p => p.sUrl == pathUrl).gCode; 

                            if (gMenuCode.IsNotNullOrEmpty())
                            {
                                //过滤出当前菜单可操作按钮
                                var buttonsInfo = info.FindAll(p => p.gMenuCode == gMenuCode&& p.sAuthorizationCode== this.buttonAuthorizationCode.ToString());
                                if (buttonsInfo.Count == 0)
                                {
                                    ActionException(filterContext, "无操作该按钮的权限！");
                                }
                            }
                            else
                            {
                                ActionException(filterContext, "无操作该菜单的权限！");
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            #endregion
        }

        /// <summary>
        /// 失败返回处理
        /// </summary>
        /// <param name="filterContext"></param>
        /// <param name="message">失败信息</param>
        /// <param name="data">返回数据</param>
        public void ActionException(ActionExecutingContext filterContext, string message)
        {
            var _Controller = filterContext.Controller as Web.Manage.BaseController;
            string alertStr = @"layerWindow.confirm('" + message+ "',{ icon:0,offset: 'auto', title: '警告' }, function(){ top.window.location='/Admin/Login/Index';});";
            var Alert = $@"<script type='text/javascript'> 
                             var layerWindow = window.top.layui.layer; 
                             {alertStr}
                        </script>";
            filterContext.Result = _Controller.Content(Alert, "text/html;charset=utf-8;");
        }
    }
}
